package com.netcracker.studportal.server.dao.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Hibernate;
import org.hibernate.Session;

import com.netcracker.studportal.server.dao.UserDAO;
import com.netcracker.studportal.server.model.User;
import com.netcracker.studportal.server.util.HibernateUtil;

public class UserDAOImpl implements UserDAO {
	private static final Logger LOG = Logger.getLogger(UserDAOImpl.class);

	@Override
	public void Add(User user, String password) throws Exception {
		Session session = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			session.beginTransaction();
			String insertQuery = 
					"INSERT INTO users (user_id, type, login, password) VALUES (" 
							+ user.getId() + ",'" 
							+ user.getType() + "','"
							+ user.getLogin() + "','" 
							+ password + "')";
			session.createSQLQuery(insertQuery).executeUpdate();
			session.getTransaction().commit();
		} catch (Exception e) {
			LOG.error("Error: ", e);
			// TODO delete it, show errors in log
			e.printStackTrace();
			throw new Exception(e);
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
	}

	@Override
	public void updateUserPassword(User user, String password) throws Exception {
		Session session = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			session.beginTransaction();
			String updateQuery = 
					"UPDATE users SET password = '" + password + "' WHERE user_id = " + user.getId();
			session.createSQLQuery(updateQuery).executeUpdate();
			session.getTransaction().commit();
		} catch (Exception e) {
			LOG.error("Error: ", e);
			// TODO delete it, show errors in log
			e.printStackTrace();
			throw new Exception(e);
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
	}

	@Override
	public User getById(Long id) throws Exception {
		Session session = null;
		User user = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			user = (User) session.load(User.class, id);
			Hibernate.initialize(user.getStudent());
			Hibernate.initialize(user.getProfessor());
		} catch (Exception e) {
			LOG.error("Error: ", e);
			// TODO delete it, show errors in log
			e.printStackTrace();
			throw new Exception(e);
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
		return user;
	}

	@Override
	public void DeleteUser(User user) throws Exception {
		Session session = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			session.beginTransaction();
			session.delete(user);
			session.getTransaction().commit();
		} catch (Exception e) {
			LOG.error("Error: ", e);
			// TODO delete it, show errors in log
			e.printStackTrace();
			throw new Exception(e);
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
	}

	@Override
	public Collection<User> getAll() throws Exception {
		Session session = null;
		List<User> users = new ArrayList<User>();
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			users = session.createCriteria(User.class).list();
		} catch (Exception e) {
			LOG.error("Error: ", e);
			// TODO delete it, show errors in log
			e.printStackTrace();
			throw new Exception(e);
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
		return users;
	}

	@Override
	public User getUserByLoginPass(String login, String passw) throws Exception {
		Session session = null;
		User user = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			String selectQuery = 
					"SELECT * FROM users WHERE login='" + login + "' AND password='" + passw + "'";
			user = (User) session.createSQLQuery(selectQuery).addEntity(User.class).uniqueResult();
		} catch (Exception e) {
			LOG.error("Error: ", e);
			// TODO delete it, show errors in log
			e.printStackTrace();
			throw new Exception(e);
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
		return user;
	}
	
	@Override
	public Long getUserID(String login, String password) throws Exception {
		Session session = null;
		Long userID = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			String selectQuery = 
					"SELECT user_id FROM users WHERE login=:login AND password=:password";
			BigDecimal user_id = (BigDecimal) session.createSQLQuery(selectQuery)
					.setString("login", login)
					.setString("password", password)
					.uniqueResult();
			 userID=user_id.longValue();
		} catch (Exception e) {
			LOG.error("Error: ", e);
			throw new Exception(e);
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
		
		return userID;
	}

	/**
	 * Realiztion of singleton.
	 */
	private UserDAOImpl() {}
	private static UserDAO instance;
	public static UserDAO getInstance() {
		if (instance == null) {
			instance = new UserDAOImpl();
		}
		return instance;
	}
}
